#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QSerialPortInfo>
#include <QTextCodec>
#include <QThread>
#include <QCoreApplication>
#include <QApplication>
#include <QSettings>
#include <QFile>
#include <QDir>
#include <QString>
#include "httplistener.h"
#include "httprequesthandler.h"
#include "requestmapper.h"
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
#include <QMessageBox>
#include <QFileDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGraphicsDropShadowEffect>
#include "function/function.h"

using namespace stefanfrings;

QString boxNumber;//箱子编号

//该方法用来搜索配置文件
QString searchConfigFile()
{
    QString binDir=QCoreApplication::applicationDirPath();
    QString appName=QCoreApplication::applicationName();
    QFile file;
    file.setFileName(binDir+"/webapp1.ini");
    if (!file.exists()) {
        file.setFileName(binDir+"/etc/webapp1.ini");
        if (!file.exists()) {
            file.setFileName(binDir+"/../etc/webapp1.ini");
            if (!file.exists()) {
                file.setFileName(binDir+"/../"+appName+"/etc/webapp1.ini");
                if (!file.exists()) {
                    file.setFileName(binDir+"/../../"+appName+"/etc/webapp1.ini");
                    if (!file.exists()) {
                        file.setFileName(binDir+"/../../../../../"+appName+"/etc/webapp1.ini");
                        if (!file.exists()) {
                            file.setFileName(QDir::rootPath()+"etc/webapp1.ini");
                        }
                    }
                }
            }
        }
    }
    if (file.exists()) {
        QString configFileName=QDir(file.fileName()).canonicalPath();	//将相对路径换成绝对路径
        qDebug("using config file %s", qPrintable(configFileName));
        return configFileName;
    }
    else {
        qFatal("config file not found");	//找不到该文件，则应用程序将输出一条错误消息，并中止程序
    }
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //设置窗口标题
    setWindowTitle("信瑞医疗手麻系统与药箱对接程序");

    //取消窗口边框
    setWindowFlags(Qt::FramelessWindowHint);
    //置顶窗口
    m_flags = windowFlags();
    setWindowFlags(m_flags | Qt::WindowStaysOnTopHint);
    show();

    //创建一个文件夹存放下载文件,已经存在返回true
    QDir dir;
    dir.mkpath(MY_PATH);//存放药箱插件文件

    COMNumber=0;
    boxNumber="0";
    sign=0;
    sendSign=0;
    ifoversend=0;

//    myserver=new QTcpServer(this);
//    //绑定和监听
//    myserver->listen(QHostAddress::Any,5001);
//    qDebug()<<__LINE__<<"ip="<<QHostAddress::Any;
//    //关联newConnection信号
//    connect(myserver,SIGNAL(newConnection()),this,SLOT(newClientLink()));




    //初始化定时器对象
    mytimer=new QTimer(this);
    //设置定时时间
    mytimer->setInterval(3000);  //1秒
    //关联timeout()信号与自定义的槽函数
    connect(mytimer,SIGNAL(timeout()),this,SLOT(timer()));
//    //启动定时器
//    mytimer->start();

    automaticConnectionPort();//自动连接端口

    //初始化定时器对象
    patienttimer=new QTimer(this);
    //设置定时时间
    patienttimer->setInterval(100);  //0.1秒
    //关联timeout()信号与自定义的槽函数
    connect(patienttimer,SIGNAL(timeout()),this,SLOT(Patienttimer()));

    //初始化定时器对象
    dynamictimer=new QTimer(this);
    //设置定时时间
    dynamictimer->setInterval(1000);  //1秒
    //关联timeout()信号与自定义的槽函数
    connect(dynamictimer,SIGNAL(timeout()),this,SLOT(Dynamictimer()));

    //配置HTTP服务器环境
    // Load the configuration file
    QString configFileName=searchConfigFile();

    QSettings* listenerSettings=new QSettings(configFileName,QSettings::IniFormat,this);
    qDebug("config file loaded");

    listenerSettings->beginGroup("listener");	//新增代码

    // Start the HTTP server     http://localhost:5001/
    RequestMapper *rm=new RequestMapper(this);
    //关联HTTP的自定义槽函数
    connect(rm, SIGNAL(sendRequesfMain(QString,QString)), this, SLOT(receRequesfMainData(QString,QString)));
    new HttpListener(listenerSettings,rm,this);//当你现在打开 http://localhost:8080/ 或 http://localhost:8080/hello，你得到 "Hello World"页。当你打开http://localhost:8080/list，将获得名称列表

    initialize();//初始化界面

//    boxNumber = "04";
//    setHttp();//设置http
//    mate=new Mate(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

//读取接收到的串口信息
void MainWindow::ReadData()
{
    QByteArray buf;
    buf = serial->readAll();

    //    QTextCodec *codec = QTextCodec::codecForName("UTF-8");//指定QString的编码方式
    QTextCodec *codec = QTextCodec::codecForName("GBK");//指定QString的编码方式
    QString name = codec->toUnicode(buf);//nameArray可以是char*，可以是QByteArray
    qDebug()<<__LINE__<<"buf= "<<name;

    //分割字符串
    QStringList mylist2=QString(buf).split("\r\n");
    for(int i=0;i<mylist2.size();i++)
    {
        if(mylist2.at(i).isEmpty())
        {
            continue;
        }

        QStringList mylist=QString(mylist2.at(i)).split(":");


        if(ifoversend>=1)
        {
            if(ifoversend>100)
            {
                qDebug()<<__LINE__<<"接收药箱药品信息失败"<<"oversendBuf="<<oversendBuf;
                ifoversend=0;
            }
            oversendBuf.append(buf);
            if(oversendBuf.contains("xxxxxxxxxx"))
            {
                qDebug()<<__LINE__<<"接收药箱药品信息成功"<<"oversendBuf="<<oversendBuf;
                ifoversend=0;

                getOversend(oversendBuf);
            }
        }
        if(mylist.at(0)=="box")
        {
            if(mylist.size()<2)
            {
                continue;
            }
            //获取箱子编号
            boxNumber=mylist.at(1);
            ifLink=1;

            addBrowser(QString("端口连接成功：%1, %2号药箱").arg(serialPortName.at(COMNumber-1)).arg(boxNumber));
            setHttp();//设置http

        }
        if(mylist.at(0)=="oversend")
        {
            if(mylist2.at(i).contains("xxxxxxxxxx"))
            {
                oversendBuf=mylist2.at(i);
                qDebug()<<__LINE__<<"接收药箱药品信息成功"<<"oversendBuf="<<oversendBuf;
                getOversend(oversendBuf);
            }
            else
            {
                oversendBuf=mylist2.at(i);
                ifoversend=1;
            }
        }
    }

//    ui->textBrowser->append(name);//把收到内容追加显示在聊天框中
//    ui->textBrowser->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);//光标移到到最后面
//    buf.clear();
}

//计时器槽函数
void MainWindow::timer()
{
    if(ifLink==1)
    {
        qDebug()<<__LINE__<<"连接成功 "<<serialPortName.at(COMNumber-1);
        ui->label_20->setText(QString("已建立信道：%1号药箱-%2").arg(boxNumber.toInt(), 2, 10, QLatin1Char('0')).arg(serialPortName.at(COMNumber-1)));
        mytimer->stop();//关闭定时器
        dynamictimer->start();
        ui->label_18->setText("程序正在运行");
        ui->label_19->show();
//        markedWords = "程序正在运行";
        markedNumber = 0;
//        serialPortName.clear();
//        COMNumber=0;
    }
    else
    {
        if(serialPortName.size()>0)
        {
            qDebug()<<__LINE__<<"无用串口 "<<serialPortName.at(COMNumber-1);
            ui->label_20->setText(QString("无用串口 %1").arg(serialPortName.at(COMNumber-1)));
        }

        if(COMNumber >= serialPortName.size())
        {
            qDebug()<<__LINE__<<"没有可用串口,正在重新扫描";

            serialPortName.clear();
            COMNumber=0;
            // 自动扫描当前可用串口，返回值追加到字符数组中
            foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
            {
                serialPortName << info.portName();
            }           

            if(serialPortName.size()==0)
            {
                ui->label_20->setText("没有可用端口,检查端口是否正常");
                if(ifPort)
                {
                    addBrowser("没有可用端口,检查端口是否正常");
                    ifPort = false;
                }
            }
            else
            {
                ifPort = true;
                qDebug()<<__LINE__<<"扫描到端口:"<<serialPortName;
                QString COMname="扫描到端口:";//把扫描到的串口名称显示在标签上
                for(int i=0;i<serialPortName.size();i++)
                {
                    COMname+=(serialPortName.at(i)+"  ");
                }
                ui->label_18->setText(COMname);
                if(serialPortName != serialPortName2)
                {
                    addBrowser(COMname);
                }
                serialPortName2 = serialPortName;
            }
        }

        for(;COMNumber<serialPortName.size();COMNumber++)
        {
            serial->close();//关闭上一个串口

            //设置串口名
            serial->setPortName(serialPortName.at(COMNumber));
            //打卡串口
            if(!serial->open(QIODevice::ReadWrite))
            {
                qDebug()<<__LINE__<<"打开串口失败 "<<serialPortName.at(COMNumber);
                continue;
            }

//            QThread::usleep(300);// 延时一点时间，不然发送串口数据失败
            //告诉MCU需要获取箱子编号
            serial->write(QString("box").toUtf8());

            COMNumber++;
            break;
        }       
    }
}

//发送病人信息定时器计时器槽函数(0.1秒)
void MainWindow::Patienttimer()
{
    if(sendSize>0)
    {
        if(sendSize<30)
        {
            int n=serial->write(sendBuf.mid(sendSign,sendSize));
            sendSize-=n;
            sendSign+=n;
        }
        else
        {
            int n=serial->write(sendBuf.mid(sendSign,20));
            sendSize-=n;
            sendSign+=n;
        }

    }
    else
    {
        patienttimer->stop();//传输完成关闭定时器
        sendSign=0;
        addBrowser("接收到手术结束信号，且已发送至药箱");
        qDebug()<<__LINE__<<"发送手术信息成功";
    }
}

//动态刷新标签提示语定时器
void MainWindow::Dynamictimer()
{
    QString str;

    for(int i=0;i<=markedNumber;i++)
    {
        str+="。";
    }
    markedNumber = (markedNumber + 1) % 3;
    ui->label_19->setText(str);
}

//如果有新的客户端连接成功,该槽函数会被自动调用
void MainWindow::newClientLink()
{
     //产生新的套接字
    sock=myserver->nextPendingConnection();

    //立马把这个套接字指针存放到我准备的容器中
    myvector.push_back(sock);

    //把新连接成功的那个客户端的ip和端口号在listwidget上显示出来
    QString ipstr=sock->peerAddress().toString();
    quint16  portnum=sock->peerPort();
    QString str=QString("%1 %2").arg(ipstr).arg(portnum);
    qDebug()<<__LINE__<<"客户端连接 "<<str;

    //关联readyRead()信号
    connect(sock,SIGNAL(readyRead()),this,SLOT(recvclientmsg()));
    //关联disconnected()信号
    connect(sock,SIGNAL(disconnected()),this,SLOT(unlink()));
}

//专门用来接收某个客户端信息的槽函数
void MainWindow::recvclientmsg()
{
//    //判断信号的发送者,谁发送的信号,信息就肯定是这个人发送过来的
//    QObject *obj=sender();
//    //类型转换
//    sockp=qobject_cast<QTcpSocket  *>(obj);

//    QByteArray buf=sockp->readAll();
////    QByteArray urlEncode = text.toPercentEncoding();//URL编码
//    QByteArray urlDecode = QByteArray::fromPercentEncoding(buf);//URL解码
//    QTextCodec *codec = QTextCodec::codecForName("UTF-8");//指定QString的编码方式
//    QString str = codec->toUnicode(urlDecode);//nameArray可以是char*，可以是QByteArray
////    qDebug()<<__LINE__<<"接收信息="<<str;

//    //截取子串,判断是get方式还是post方式发送
//    QString otherstr=str.split("\r\n").at(0);
////    qDebug()<<__LINE__<<"otherstr="<<otherstr;
//    if(otherstr.contains("GET /"))
//    {
//        qDebug()<<__LINE__<<"GET方式发送信息";
//        //分割字符串
//        QStringList mylist=str.split("\r\n");
//        if(otherstr.contains("Box_number"))
//        {
//            sockp->write(boxNumber.toUtf8());//发送药箱编号
//            qDebug()<<__LINE__<<"发送药箱编号:"<<boxNumber.toUtf8();
//        }
//        else
//        {
//            qDebug()<<__LINE__<<"未知数据";
//        }

////        for(int i=0; i<mylist.size(); i++)
////        {
////            qDebug()<<__LINE__<<"解析数据:"<<mylist.at(i);
////        }
//    }
//    else if(otherstr.contains("POST /"))
//    {
//        qDebug()<<__LINE__<<"POST方式发送信息";
//        //分割字符串
//        QStringList mylist=str.split("\r\n");
//        if(otherstr.contains("opinf"))
//        {
//            patientInfo=mylist.at(mylist.size()-1);//获取病人手术信息
//            qDebug()<<__LINE__<<"病人手术信息:"<<patientInfo;
//        }
//        else if(otherstr.contains("over_light"))
//        {
//            QString over_light=mylist.at(mylist.size()-1);//获取病人手术信息
//            qDebug()<<__LINE__<<"over_light:"<<over_light;
//        }
//        else if(otherstr.contains("bottle_state"))
//        {
//            QString bottle_state=mylist.at(mylist.size()-1);//获取病人手术信息
//            qDebug()<<__LINE__<<"bottle_state:"<<bottle_state;
//        }
//        else
//        {
//            qDebug()<<__LINE__<<"未知数据";
//        }
////        for(int i=0; i<mylist.size(); i++)
////        {
////            qDebug()<<__LINE__<<"解析数据:"<<mylist.at(i);
////        }

//    }
//    else
//    {
//        qDebug()<<__LINE__<<"未知方式发送信息";
//    }
}

//客户端断开了
void MainWindow::unlink()
{
    //获取信号的发送者,谁发的信号,证明谁断开
    QObject *obj=sender();
    QTcpSocket *sockp=qobject_cast<QTcpSocket *>(obj);
    QString ipstr=sockp->peerAddress().toString();
    quint16 portnum=sockp->peerPort();
    QString buf=QString("%1 %2").arg(ipstr).arg(portnum);

    //从容器中把断开的客户端套接字删除
     myvector.removeOne(sockp);
     qDebug()<<__LINE__<<"客户端断开  "<<buf;
}

void MainWindow::requestFinished(QNetworkReply *reply)
{
//    QString loginResultJson;
    QByteArray buf = reply->readAll();

    QJsonParseError myerr;
    QJsonDocument mydoc=QJsonDocument::fromJson(buf,&myerr);

    //获取最外面的对象
    QJsonObject obj=mydoc.object();

    token = obj.value("token").toString().toLatin1();
    qDebug()<<__LINE__<<QString(token);

//    // 获取http状态码
//    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
//    if(statusCode.isValid())
//    {
//        qDebug() << "status code=" << statusCode.toInt();
//    }

//    QNetworkReply::NetworkError err = reply->error();
//    if(err != QNetworkReply::NoError)
//    {
//        qDebug() << "Failed: " << reply->errorString();
//    }
//    else
//    {
//        // 获取返回内容
//        //qDebug() << "loginResultJson  is  " <<  QString::fromStdString(bytes.toStdString());
//        loginResultJson =  QString::fromStdString(token.toStdString());
//        //处理返回数据
//    }

    getInfo();//获取更新服务器信息
}

//接收服务器回复的应答信息
void MainWindow::recvhttp(QNetworkReply *reply)
{
    //读取http应答信息
   QByteArray buf=reply->readAll();
   if(buf.isEmpty())
   {
       return;
   }

//   qDebug()<<__FILE__<<QString(buf);

   //根据实际填写路径,把药品设置表信息保存在本地
   QFile file(QString("%1药品设置表.json").arg(MY_PATH));
   if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate))
   {
       qDebug() << "file error!";
   }
   QTextStream stream(&file);
   stream.setCodec("UTF-8");		// 设置写入编码是UTF8
   // 写入文件
   stream << QString(buf);
   file.close();   // 关闭file

   //把获取的json数据标准化存储
   QJsonParseError myerr;
   QJsonDocument mydoc=QJsonDocument::fromJson(buf,&myerr);

   //获取最外面的对象
   QJsonObject obj=mydoc.object();

   settingTable=obj.value("data").toArray();

//   QJsonArray val=obj.value("data").toArray();
   //qDebug()<<val;

}

//接收服务器回复的应答信息
void MainWindow::recvhttp2(QNetworkReply *reply)
{
    //读取http应答信息
    QByteArray buf=reply->readAll();
    if(buf.isEmpty())
    {
        return;
    }
    //   qDebug()<<QString(buf);

    //根据实际填写路径,把NFC种类表信息保存在本地
    QFile file(QString("%1NFC种类表.json").arg(MY_PATH));
    if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate))
    {
       qDebug() << __LINE__ << "NFC种类表 file error!";
    }
    QTextStream stream(&file);
    stream.setCodec("UTF-8");		// 设置写入编码是UTF8
    // 写入文件
    stream << QString(buf);
    file.close();   // 关闭file

    //把获取的json数据标准化存储
    QJsonParseError myerr;
    QJsonDocument mydoc=QJsonDocument::fromJson(buf,&myerr);

    //剥洋葱
    //获取最外面的对象
    QJsonObject obj=mydoc.object();

    //obj存放的就是
    //继续获取键值对中的键和值
    //   QJsonObject  obj1=obj.toObject();
    QJsonArray val=obj.value("data2").toArray();
    NFCtable=val;

    //val存放的就是
    QJsonObject  obj1=val.at(0).toObject();

    //obj1存放的就是({"name":"","position":"H19","size":"","sizeUnit":""})
    QJsonValue val1=obj1.value("position");


    //名称
    QJsonValue val2=obj1.value("name");
    qDebug()<<val2.toString();
    //标记
    QJsonValue val3=obj1.value("mark");
    qDebug()<<val3.toString();
    //型号
    QJsonValue val4=obj1.value("unit");
    qDebug()<<val4.toString();
    //生产商
    QJsonValue val5=obj1.value("factory");
    qDebug()<<val5.toString();
    //产地
    QJsonValue val6=obj1.value("origin_place");
    qDebug()<<val6.toString();
}

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
//    光标位置
//    QCursor *cursor;
//    int x=cursor->pos().x()-100;
//    int y=cursor->pos().y()-100;
    //qDebug()<<"x=="<<x<<"y=="<<y;
    if(ui->pushButton==watched)
    {
        if(QEvent::Enter==event->type())
        {
            //设置匹对结果按钮
            ui->pushButton->setIcon(QPixmap(":/new/prefix1/resource/15.png"));
            ui->pushButton->setStyleSheet("background: #FBFBFB;color: rgb(127, 190, 226);font: 25 11pt \"Microsoft YaHei\";border-radius: 6px;");
        }
        else if(QEvent::Leave==event->type())
        {
            ui->pushButton->setIcon(QPixmap(":/new/prefix1/resource/6.png"));
            ui->pushButton->setStyleSheet("background: #FBFBFB;color: rgb(102, 102, 102);font: 25 11pt \"Microsoft YaHei\";border-radius: 6px;");
        }
    }
    if(ui->pushButton_2==watched)
    {
        if(QEvent::Enter==event->type())
        {
            //设置重新启动按钮
            ui->pushButton_2->setIcon(QPixmap(":/new/prefix1/resource/14.png"));
            ui->pushButton_2->setStyleSheet("background: #FBFBFB;color: rgb(127, 190, 226);font: 25 11pt \"Microsoft YaHei\";border-radius: 6px;");
        }
        else if(QEvent::Leave==event->type())
        {
            ui->pushButton_2->setIcon(QPixmap(":/new/prefix1/resource/8.png"));
            ui->pushButton_2->setStyleSheet("background: #FBFBFB;color: rgb(102, 102, 102);font: 25 11pt \"Microsoft YaHei\";border-radius: 6px;");
        }
    }
    if(ui->pushButton_3==watched)
    {
        if(QEvent::Enter==event->type())
        {
            //设置展开按钮
            if(sign==0)
            {
                ui->pushButton_3->setIcon(QPixmap(":/new/prefix1/resource/13.png"));
                ui->pushButton_3->setStyleSheet("background: #FBFBFB;color: rgb(127, 190, 226);font: 25 11pt \"Microsoft YaHei\";border-radius: 6px;");
            }
            else
            {
                ui->pushButton_3->setIcon(QPixmap(":/new/prefix1/resource/18.png"));
                ui->pushButton_3->setStyleSheet("background: #FBFBFB;color: rgb(127, 190, 226);font: 25 11pt \"Microsoft YaHei\";border-radius: 6px;");
            }
        }
        else if(QEvent::Leave==event->type())
        {
            if(sign==0)
            {
                ui->pushButton_3->setIcon(QPixmap(":/new/prefix1/resource/7.png"));
                ui->pushButton_3->setStyleSheet("background: #FBFBFB;color: rgb(102, 102, 102);font: 25 11pt \"Microsoft YaHei\";border-radius: 6px;");
            }
            else
            {
                ui->pushButton_3->setIcon(QPixmap(":/new/prefix1/resource/17.png"));
                ui->pushButton_3->setStyleSheet("background: #FBFBFB;color: rgb(102, 102, 102);font: 25 11pt \"Microsoft YaHei\";border-radius: 6px;");
            }
        }
    }
    if(ui->pushButton_4==watched)
    {
        if(QEvent::Enter==event->type())
        {
            ui->tooltip->setGeometry(458,36,74,24);
            ui->tooltip->show();
            if (m_flags == NULL)
            {
                ui->pushButton_4->setIcon(QPixmap(":/new/prefix1/resource/16.png"));
                ui->tooltip->setText("置顶");
            }
            else
            {
                ui->pushButton_4->setIcon(QPixmap(":/new/prefix1/resource/16.png"));
                ui->tooltip->setText("取消置顶");
            }
//            qDebug()<<__LINE__<<"置顶悬停";
        }
        else if(QEvent::Leave==event->type())
        {
            ui->pushButton_4->setIcon(QPixmap(":/new/prefix1/resource/10.png"));
            ui->tooltip->close();
        }
    }
    if(ui->pushButton_5==watched)
    {
        if(QEvent::Enter==event->type())
        {
            ui->tooltip->setGeometry(502,36,74,24);
            ui->tooltip->setText("最小化");
            ui->tooltip->show();
        }
        else if(QEvent::Leave==event->type())
        {
            ui->tooltip->close();
        }
    }
    if(ui->pushButton_6==watched)
    {
        if(QEvent::Enter==event->type())
        {
            ui->tooltip->setGeometry(547,36,74,24);
            ui->tooltip->show();
            if(ifWinMax)
            {
                ui->tooltip->setText("最大化");
            }
            else
            {
                ui->tooltip->setText("向下还原");
            }
        }
        else if(QEvent::Leave==event->type())
        {
            ui->tooltip->close();
        }
    }
    if(ui->pushButton_7==watched)
    {
        if(QEvent::Enter==event->type())
        {
            ui->tooltip->setGeometry(591,36,50,24);
            ui->tooltip->setText("关闭");
            ui->tooltip->show();
        }
        else if(QEvent::Leave==event->type())
        {
            ui->tooltip->close();
        }
    }
    return QObject::eventFilter(watched,event);
}

//初始化界面
void MainWindow::initialize()
{
    //部件事件过滤的注册
    ui->pushButton->installEventFilter(this);
    ui->pushButton_2->installEventFilter(this);
    ui->pushButton_3->installEventFilter(this);
    ui->pushButton_4->installEventFilter(this);
    ui->pushButton_5->installEventFilter(this);
    ui->pushButton_6->installEventFilter(this);
    ui->pushButton_7->installEventFilter(this);

    //设置窗口大小
    this->resize(650,360);

    ui->label_19->hide();

    ui->pushButton_5->setIcon(QPixmap(":/new/prefix1/resource/11.png"));

//    QFont font;
//    font.setFamily("MicrosoftYaHei");//设置字体
//    //设置为粗体
////    font.setBold(true);
//    //字体大小
//    font.setPointSize(10);
//    ui->textBrowser->setFont(font);
    ui->textBrowser->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//设置垂直滚动条不可见
    ui->textBrowser->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//设置水平滚动条不可见

    //设置标题字间距
    QFont font2;
    font2.setLetterSpacing(QFont::PercentageSpacing,120);//120字间距，默认100

    ui->label_20->setFont(font2);
    ui->label_18->setFont(font2);
    ui->pushButton_8->setFont(font2);
    ui->pushButton_9->setFont(font2);

    connect(&manager,SIGNAL(finished(QNetworkReply *)),this,SLOT(recvhttp(QNetworkReply *)));
    connect(&manager2,SIGNAL(finished(QNetworkReply *)),this,SLOT(recvhttp2(QNetworkReply *)));

    {

        //设置展开按钮
        ui->pushButton_3->setIcon(QPixmap(":/new/prefix1/resource/7.png"));
        //设置具体阴影
        QGraphicsDropShadowEffect *shadow_effect = new QGraphicsDropShadowEffect(this);
        shadow_effect->setOffset(0, 0);

        //阴影颜色
        shadow_effect->setColor(QColor(38, 78, 119, 127));
        //阴影半径
        shadow_effect->setBlurRadius(10);
        ui->pushButton_3->setGraphicsEffect(shadow_effect);
//        ui->pushButton_3->setStyleSheet("background: #FBFBFB;font: 25 11pt \"Microsoft YaHei\";box-shadow: 0px 0px 6px 0px rgba(11, 65, 96, 0.3);border-radius: 6px;text-align : left;padding-left: 30px;");
//        ui->pushButton_2->setIcon(QPixmap(":/new/prefix1/resource/8.png"));
//        ui->pushButton->setIcon(QPixmap(":/new/prefix1/resource/6.png"));
//        QLabel *pStatus = new QLabel();
//        QVBoxLayout *pVBLayout = new QVBoxLayout();
//        QHBoxLayout *pHBLayout = new QHBoxLayout();

//        pHBLayout->addStretch();                //添加可伸缩项
//        pHBLayout->addWidget(pStatus);
//        pHBLayout->setContentsMargins(1,5,0,0);

//        pVBLayout->addStretch();
//        pVBLayout->addLayout(pHBLayout);
//        pVBLayout->setMargin(22);
//        ui->pushButton_3->setLayout(pVBLayout);

////        ui->pushButton_3->setFixedSize(50, 50);          //头像大小可根据实际需求修改
//        pStatus->setFixedSize(18, 10);        //状态大小可根据实际需求修改
////        pStatus->set
////        ui->pushButton_3->setStyleSheet("background: red; border-radius: 8px;");    //圆角大小可根据实际需求修改
//        pStatus->setStyleSheet("border-image: url(:/new/prefix1/resource/7.png);"); //圆角大小可根据实际需求修改
    }
    {
        //设置重新启动
        ui->pushButton_2->setIcon(QPixmap(":/new/prefix1/resource/8.png"));
        //设置具体阴影
        QGraphicsDropShadowEffect *shadow_effect = new QGraphicsDropShadowEffect(this);
        shadow_effect->setOffset(0, 0);

        //阴影颜色
        shadow_effect->setColor(QColor(38, 78, 119, 127));
        //阴影半径
        shadow_effect->setBlurRadius(10);
        ui->pushButton_2->setGraphicsEffect(shadow_effect);
    }
    {
        //设置匹对结果按钮
        ui->pushButton->setIcon(QPixmap(":/new/prefix1/resource/6.png"));
        //设置具体阴影
        QGraphicsDropShadowEffect *shadow_effect = new QGraphicsDropShadowEffect(this);
        shadow_effect->setOffset(0, 0);

        //阴影颜色
        shadow_effect->setColor(QColor(38, 78, 119, 127));
        //阴影半径
        shadow_effect->setBlurRadius(10);
        ui->pushButton->setGraphicsEffect(shadow_effect);
    }
    {
        //设置鼠标悬停提示框标签
        ui->tooltip->hide();//先隐藏
        //设置具体阴影
        QGraphicsDropShadowEffect *shadow_effect = new QGraphicsDropShadowEffect(this);
        shadow_effect->setOffset(0, 0);

        //阴影颜色
        shadow_effect->setColor(QColor(38, 78, 119, 127));
        //阴影半径
        shadow_effect->setBlurRadius(10);
        ui->tooltip->setGraphicsEffect(shadow_effect);
    }

    {
        //打开保存的药品设置表数据
        QFile myfile2(QString("%1药品设置表.json").arg(MY_PATH));
        if (myfile2.open(QIODevice::ReadOnly))
        {
            // 读取文件的全部内容
            QTextStream stream2(&myfile2);
            stream2.setCodec("UTF-8");		// 设置读取编码是UTF8
            QString json_str2=stream2.readAll();
            myfile2.close();   // 关闭file

            //把获取的json数据标准化存储
            QJsonParseError myerr2;
            QJsonDocument mydoc2=QJsonDocument::fromJson(json_str2.toUtf8(),&myerr2);

            //获取最外面的对象
            QJsonObject obj2=mydoc2.object();
            settingTable=obj2.value("data").toArray();
        }
        else
        {
            qDebug() << "药品设置表 file error!";
        }

    }

    {
        //打开保存的药品设置表数据
        QFile myfile2(QString("%1NFC种类表.json").arg(MY_PATH));
        if (myfile2.open(QIODevice::ReadOnly))
        {
            // 读取文件的全部内容
            QTextStream stream2(&myfile2);
            stream2.setCodec("UTF-8");		// 设置读取编码是UTF8
            QString json_str2=stream2.readAll();
            myfile2.close();   // 关闭file

            //把获取的json数据标准化存储
            QJsonParseError myerr2;
            QJsonDocument mydoc2=QJsonDocument::fromJson(json_str2.toUtf8(),&myerr2);

            //获取最外面的对象
            QJsonObject obj2=mydoc2.object();
            NFCtable=obj2.value("data").toArray();
        }
        else
        {
            qDebug() << "NFC种类表 file error!";
        }

    }
}

//解析传过来的病人手术信息 Key=P_idnum
QString MainWindow::ParseData(QString Data,QString Key)
{
    //接收病人手术信息  "label=0035982514&value=0035982514&P_idnum=0035982514&P_name=李三&P_age=35&P_sex=男&Blood_t=O&An_mt=局部麻醉&Op_name=阑尾炎切除手术&"
    QStringList DataList=Data.split("&");
    for(int i=0;i<DataList.size();i++)
    {
        QStringList KeyList=DataList.at(i).split("=");
        if(KeyList.size()>=2)
        {
            if(KeyList.at(0)==Key)
            {
                return KeyList.at(1);
            }
        }
    }

    return "";
}

//设置核对接收到的药品信息
void MainWindow::getOversend(QString Data)
{
    QString oversendBuf = Data;
    oversendBuf=oversendBuf.replace("oversend:","");
    oversendBuf=oversendBuf.replace("xxxxxxxxxx","");
    oversendBuf=oversendBuf.replace("\r\n","");
    oversendBuf=oversendBuf.replace("\r","");
//    oversendBuf=oversendBuf.replace("'","\"");
    addBrowser(QString("智能药箱实际的数据：%1").arg(oversendBuf));

    mt=new Mate();
    topMostSlot(mt);//置顶窗口
    mt->setCheckInfo(patientInfo,pharmacyInfo,oversendBuf,settingTable,NFCtable);
}

//设置http
void MainWindow::setHttp()
{
    //登入账号http://192.168.3.109:8888/hardware/upload-image/
    QNetworkRequest request;
    QNetworkAccessManager* naManager = new QNetworkAccessManager(this);
    connect(naManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));

    request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
    request.setUrl(QUrl::fromUserInput(URLName("/api/client/login/")));
//    request.setUrl(QUrl::fromUserInput(URLName("/api/management-client/login/")));

    QJsonObject object;
    object.insert("username",l_username);
    object.insert("password",l_password);

    QByteArray byte_array = QJsonDocument(object).toJson();
    qDebug()<< "user  info " << object;
//    QNetworkReply* reply = naManager->post(request,byte_array);//发起post请求
    naManager->post(request,byte_array);//发起post请求
}

//获取更新服务器信息
void MainWindow::getInfo()
{
    //获取药品设置表
    QUrl url(URLName(QString("/api/client/drug-setting/?id=%1").arg(boxNumber)));
    //创建http请求
    QNetworkRequest req(url);
    req.setRawHeader("token",token);
//    qDebug()<<__LINE__<<token;

    //发送该请求
    manager.get(req);
//    QEventLoop eventLoop;
//    QTimer::singleShot(overtime_http, &eventLoop, &QEventLoop::quit);
//    connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
//    eventLoop.exec(QEventLoop::ExcludeUserInputEvents);

//    QByteArray data = reply->readAll();
//    qDebug()<<__LINE__<<QString(data);


//    QTimer timer;
//    timer.setInterval(5000);    // 设置超时时间
//    timer.setSingleShot(true);  // 单次触发


    //获取NFC种类表
    QUrl url2(URLName("/api/client/nfctype/"));
    //创建http请求
    QNetworkRequest req2(url2);
    req2.setRawHeader("token",token);
    //发送该请求
    manager2.get(req2);
}

//置顶窗口
void MainWindow::topMostSlot(QWidget *parent)
{
    if(parent == this)
    {
        if (m_flags == NULL)
        {
            m_flags = windowFlags();
            parent->setWindowFlags(m_flags | Qt::WindowStaysOnTopHint);//置顶窗口
            parent->show();
        }
        else
        {
            m_flags = NULL;
            parent->setWindowFlags(m_flags | Qt::FramelessWindowHint);//取消窗口边框
            parent->show();
        }
    }
    else
    {
        if (m_flags == NULL)
        {
            parent->setWindowFlags(m_flags);//取消置顶
            parent->show();
        }
        else
        {
            m_flags = windowFlags();
            parent->setWindowFlags(m_flags | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);//置顶窗口
            parent->show();
        }
    }

}

//追加数据到文本框框中
void MainWindow::addBrowser(QString Data)
{
    QDate mydate=QDate::currentDate();
    QTime mytime=QTime::currentTime();

    //记录当前时间
    QString TimeD = mydate.toString("yyyy-MM-dd");
    QString TimeS = mytime.toString("hh:mm:ss");

//    ui->textBrowser->append(QString("%1 %2  %3").arg(TimeD).arg(TimeS).arg(Data));//把收到内容追加显示在聊天框中
    ui->textBrowser->insertPlainText(QString("%1 %2  %3\n").arg(TimeD).arg(TimeS).arg(Data));//把收到内容追加显示在聊天框中
}

//自动连接端口
void MainWindow::automaticConnectionPort()
{
    // 自动扫描当前可用串口，返回值追加到字符数组中
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        serialPortName << info.portName();
    }

    if(serialPortName.size()==0)
    {
        ui->label_20->setText("没有可用端口,检查端口是否正常");
        if(ifPort)
        {
            addBrowser("没有可用端口,检查端口是否正常");
            ifPort = false;
        }
    }
    else
    {
        qDebug()<<__LINE__<<"扫描到端口:"<<serialPortName;
        QString COMname="扫描到端口：";//把扫描到的串口名称显示在标签上
        for(int i=0;i<serialPortName.size();i++)
        {
            COMname+=(serialPortName.at(i)+"  ");
        }
        ui->label_18->setText(COMname);

        addBrowser(COMname);
    }
    serialPortName2 = serialPortName;

    //初始化串口协议
    serial = new QSerialPort;
    //设置波特率
    serial->setBaudRate(9600);
    //设置数据位数
    serial->setDataBits(QSerialPort::Data8);
    //设置流控制
    serial->setFlowControl(QSerialPort::NoFlowControl);
    //连接串口接收信号槽
    connect(serial,SIGNAL(readyRead()),this,SLOT(ReadData()));

    for(;COMNumber<serialPortName.size();COMNumber++)
    {
        //设置串口名
        serial->setPortName(serialPortName.at(COMNumber));
        //打卡串口
        if(!serial->open(QIODevice::ReadWrite))
        {
            qDebug()<<__LINE__<<"打开串口失败 "<<serialPortName.at(COMNumber);
            ui->label_20->setText(QString("打开串口失败 %1").arg(serialPortName.at(COMNumber)));
            serial->close();
            continue;
        }



        QThread::usleep(300);// 延时一点时间，不然发送串口数据失败
        //告诉MCU需要获取箱子编号
        serial->write(QString("box").toUtf8());

        COMNumber++;

        break;
    }

    //启动定时器
    mytimer->start();
}

//匹对界面
void MainWindow::on_pushButton_clicked()
{
    mt=new Mate();
    topMostSlot(mt);//置顶窗口

    mt->setCheckInfo(patientInfo,pharmacyInfo,oversendBuf,settingTable,NFCtable);
}

//重启按钮
void MainWindow::on_pushButton_2_clicked()
{
    addBrowser("重启程序");
    serialPortName.clear();
    COMNumber=0;
    ifLink=0;
    delete serial;
    serial=nullptr;

    dynamictimer->stop();
    ui->label_19->hide();
    automaticConnectionPort();//自动连接端口


}

//连接自定义HTTP槽函数
void MainWindow::receRequesfMainData(QString number, QString data)
{
    if(number=="0")
    {
        qDebug()<<__LINE__<<"成功发送箱子编号";
    }
    else if(number=="1")
    {
        //设置窗口大小
//        this->resize(650,700);
        sign=1;

        //接收病人手术信息  "label=0035982514&value=0035982514&P_idnum=0035982514&P_name=李三&P_age=35&P_sex=男&Blood_t=O&An_mt=局部麻醉&Op_name=阑尾炎切除手术&"
        addBrowser(QString("手术信息：%1").arg(data));
        qDebug()<<__LINE__<<"data="<<data;

        QString P_name=ParseData(data,"P_name");
        QString P_sex=ParseData(data,"P_sex");
        QString Blood_t=ParseData(data,"Blood_t");
        QString P_age=ParseData(data,"P_age");
        QString P_idnum=ParseData(data,"P_idnum");
        QString An_mt=ParseData(data,"An_mt");
        QString Op_name=ParseData(data,"Op_name");

//        ui->label_6->setText(P_name);
//        ui->label_8->setText(P_sex);
//        ui->label_10->setText(Blood_t);
//        ui->label_12->setText(P_age);
//        ui->label_13->setText(P_idnum);
//        ui->label_15->setText(An_mt);
//        ui->label_17->setText(Op_name);

        QJsonObject bzero;
        patientInfo=bzero;
        //病人信息保存在键值对
        patientInfo.insert("P_name",P_name);
        patientInfo.insert("P_sex",P_sex);
        patientInfo.insert("Blood_t",Blood_t);
        patientInfo.insert("P_age",P_age);
        patientInfo.insert("P_idnum",P_idnum);
        patientInfo.insert("An_mt",An_mt);
        patientInfo.insert("Op_name",Op_name);

        QJsonDocument document=QJsonDocument(patientInfo);
        sendBuf="op_inf:";
        sendBuf += (document.toJson()+="xxxxxxxxxx");// 转换成QByteArray
        //把病人信息发送给药箱
//        serial->write(sendBuf);
        sendSize=sendBuf.size();

        patienttimer->start();//开启传输手术信息定时器

        qDebug()<<"sendBuf="<<sendBuf;
    }
    else if(number=="2")
    {
        serial->write("over");
        qDebug()<<__LINE__<<"over";
    }
    else if(number=="3")
    {
        pharmacyInfo=data;
        addBrowser(QString("手麻系统记录的数据：%1").arg(data));
    }
}

//展开按钮
void MainWindow::on_pushButton_3_clicked()
{
    if(sign==0)
    {
        sign=1;
        //展开窗口,设置窗口大小
        this->resize(650,700);
        //设置展开按钮
//        QPixmap pixmap(":/new/prefix1/resource/7.png");
//        QMatrix leftmatrix;
//        leftmatrix.rotate(270);
//        ui->pushButton_3->setPixmap(pixmap.transformed(leftmatrix,Qt::SmoothTransformation));
        ui->pushButton_3->setIcon(QPixmap(":/new/prefix1/resource/18.png"));
        ui->pushButton_3->setText("  收缩");
    }
    else
    {
        sign=0;
        //隐藏窗口,设置窗口大小
        this->resize(650,360);
        //设置展开按钮
        ui->pushButton_3->setIcon(QPixmap(":/new/prefix1/resource/13.png"));
        ui->pushButton_3->setText("  展开");
    }
}

//置顶按钮
void MainWindow::on_pushButton_4_clicked()
{
    topMostSlot(this);//置顶窗口
}

bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    MSG* msg = (MSG*)message;
    switch(msg->message)
    {
    case WM_NCHITTEST:
        int xPos = GET_X_LPARAM(msg->lParam) - this->frameGeometry().x();
        int yPos = GET_Y_LPARAM(msg->lParam) - this->frameGeometry().y();
        if(this->childAt(xPos,yPos) == 0)
        {
            *result = HTCAPTION;
        }else{
            return false;
        }
        if(xPos > 0 && xPos < 8)
            *result = HTLEFT;
        if(xPos > (this->width() - 8) && xPos < (this->width() - 0))
            *result = HTRIGHT;
        if(yPos > 0 && yPos < 8)
            *result = HTTOP;
        if(yPos > (this->height() - 8) && yPos < (this->height() - 0))
            *result = HTBOTTOM;
        if(xPos > 18 && xPos < 22 && yPos > 18 && yPos < 22)
            *result = HTTOPLEFT;
        if(xPos > (this->width() - 22) && xPos < (this->width() - 18) && yPos > 18 && yPos < 22)
            *result = HTTOPRIGHT;
        if(xPos > 18 && xPos < 22 && yPos > (this->height() - 22) && yPos < (this->height() - 18))
            *result = HTBOTTOMLEFT;
        if(xPos > (this->width() - 22) && xPos < (this->width() - 18) && yPos > (this->height() - 22) && yPos < (this->height() - 18))
            *result = HTBOTTOMRIGHT;
        return true;
    }
    return false;
}

void MainWindow::mousePressEvent(QMouseEvent *e)
{
    if(e->button()==Qt::LeftButton)
        clickPos=e->pos();
}

void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
    if(e->buttons()&Qt::LeftButton)
        move(e->pos()+pos()-clickPos);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
//    int res = QMessageBox::question(this, "提醒","关闭将断开端口连接", "确定", "取消");
//    if (res == 1)
//    {
//        event -> ignore();
//    }
}

//最小化按钮
void MainWindow::on_pushButton_5_clicked()
{
    this->showMinimized();
}

//最大化按钮
void MainWindow::on_pushButton_6_clicked()
{
    if(ifWinMax)
    {
        ifWinMax = false;
        this->showMaximized();//窗口最大化
        ui->pushButton_6->setStyleSheet("background: #FBFBFB;font: 25 11pt \"Microsoft YaHei\";box-shadow: 0px 0px 6px 0px rgba(11, 65, 96, 0.3);border-radius: 1px;border-image: url(:/new/prefix1/resource/12.png);");
    }
    else
    {
        ifWinMax = true;
        this->showNormal();//窗口返回最大化前大小
        ui->pushButton_6->setStyleSheet("background: #FBFBFB;font: 25 11pt \"Microsoft YaHei\";box-shadow: 0px 0px 6px 0px rgba(11, 65, 96, 0.3);border-radius: 1px;border-image: url(:/new/prefix1/resource/4.png);");
    }

}

//关闭按钮
void MainWindow::on_pushButton_7_clicked()
{
    this->close();
}

//清空文本框按钮
void MainWindow::on_pushButton_9_clicked()
{
    ui->textBrowser->clear();
}

//文本框内容导入txt按钮
void MainWindow::on_pushButton_8_clicked()
{
//    //弹出文件对话框
//    QString path=QFileDialog::getOpenFileName(this,"文件对话框");
//    qDebug()<<__LINE__<<path;

//    //弹出目录对话框--》只显示目录
//    QString dirpath=QFileDialog::getExistingDirectory(this);
//    qDebug()<<__LINE__<<dirpath;

    QDate mydate=QDate::currentDate();
    QTime mytime=QTime::currentTime();
    //记录当前时间
    QString TimeD = mydate.toString("yyyy-MM-dd");
    QString TimeS = mytime.toString("hh-mm-ss");

    QString defaultPath = QString("C:/%1_%2").arg(TimeD).arg(TimeS);//设置默认保存路径
    QString fileName= QFileDialog::getSaveFileName(this,tr("导入信息到.txt"), defaultPath,tr("txt File (*.txt)"));
    qDebug()<<__LINE__<<fileName;
    if(fileName.isEmpty())
    {
        qDebug()<<__LINE__<<"没有选择路径，退出";
        return;
    }

    //获取textBrowser修改以后的内容
    QString PlainTextStr=ui->textBrowser->toPlainText();
//    qDebug()<<__LINE__<<PlainTextStr;

    //创建QFile
    QFile myfile(fileName);
    //打开清空原来文件
    bool ret=myfile.open(QIODevice::Truncate|QIODevice::ReadWrite);
    if(!ret)
    {
        QMessageBox::critical(this,"打开失败","打开文件失败",QMessageBox::Ok);
        qDebug()<<"打开文件失败";
        return;
    }
    //把新内容写入的原文件中
    myfile.write(PlainTextStr.toUtf8());
    QMessageBox::information(this,"保存成功","保存文件成功",QMessageBox::Ok);

    //清空路径.方便下次重新打开文件
    fileName.clear();
    //关闭文件
    myfile.close();
}
